#include "ccombobox.h"

/**
 * CComboBox - constructor, creates list of items
 * @param comboItems
 */
CComboBox::CComboBox(vector<CTextListItem> comboItems) {
  init();
  setComboItems(comboItems);
}
//---------------------------------------------------------------------------

/**
 * CComboBox - constructor, creates list of items
 * @param comboItems
 */
CComboBox::CComboBox(vector<string> comboItems) {
  init();
  setComboItems(comboItems);
}
//---------------------------------------------------------------------------

/**
 * CComboBox - constructor, creates list of items
 * @param comboItems
 * @param comboItemIds
 */
CComboBox::CComboBox(vector<string> comboItems, vector<int> comboItemIds) {
  init();
  setComboItems(comboItems, comboItemIds);
}
//---------------------------------------------------------------------------

/**
 * init - initialization
 */
void CComboBox::init() {
  CDynamicGuiObject::init();
  comboItemHeight = 0;
  popUp = false;
}
//---------------------------------------------------------------------------

/**
 * getSelection - returns selected item
 * @return selected item
 */
vector<CTextListItem>::iterator CComboBox::getSelection() const {
  return sel;
}
//---------------------------------------------------------------------------

/**
 * isFocused - returns true if cursor is located above component
 * @param eventPtr
 * @return true/false cursor is/is not above component
 */
bool CComboBox::isFocused(CMouseEvent* eventPtr) {

  // Temporary variables
  int l(x), t(y), r(x + width), b(y + height);
  int mx(eventPtr->getMouseX()), my(eventPtr->getMouseY());
  bool click(dynamic_cast<CMouseClickEvent*> (eventPtr));

  // If mouse is above component, it is focused
  if (mx >= l && my >= t && mx <= r && my <= b) {
    popUp = click ? !popUp : popUp;
    return true;
  }

  // If clicked on item in selection menu, select it and hide the menu
  if (popUp && click) {
    int py = b + 1;
    vector<CTextListItem>::iterator i = comboItems.begin();
    for (; i != comboItems.end(); i++, py += comboItemHeight) {
      if (mx >= l && my >= py && mx <= r && my <= py + comboItemHeight) {
        sel = i;
        text = (*i).getValue();
        popUp = false;
        return true;
      }
    }
  }
  return false;
}
//---------------------------------------------------------------------------

/**
 * drawSelf - draw combo
 * @param rendererPtr
 */
void CComboBox::drawSelf(CGuiRenderer* rendererPtr) {

  // Combo dimensions without border
  unsigned short w(width - (style.getBorder().getSize() << 1));
  unsigned short h(height - (style.getBorder().getSize() << 1));

  // Combo text dimensions
  unsigned short textW(rendererPtr->calculateTTFWidth(fontId, text));
  unsigned short textH(rendererPtr->calculateTTFHeight(fontId));
  comboItemHeight = textH;

  // If text fits into combo, draw it
  string tmp(text);
  if (textH <= h && this->fitTextToWidth(tmp, textW, w, rendererPtr)) {
    int l(x + ((width - textW) >> 1)), t(y + ((height - textH) >> 1));
    rendererPtr->drawTextRect(l, t, l + textW, t + textH, fontId, tmp);
  }

  // If popup menu is active, draw it
  if (popUp) {
    int py(y + height + 1);
    rendererPtr->drawRect(x, py, x + width, py + comboItemHeight
        * comboItems.size(), style.getAlpha(), style.getColor(),
        style.getImgId());
    vector<CTextListItem>::iterator i = comboItems.begin();
    for (; i != comboItems.end(); i++, py += comboItemHeight) {
      tmp = (*i).getValue();
      unsigned short tmpW(rendererPtr->calculateTTFWidth(fontId, tmp));
      if (this->fitTextToWidth(tmp, tmpW, width, rendererPtr)) {
        rendererPtr->drawTextRect(x, py, x + width, py + comboItemHeight,
            fontId, tmp);
      }
    }
  }
}
//---------------------------------------------------------------------------

/**
 * isOverlap - returns true if component overlaps its standart dimensions
 * @param rect
 * @return true/false component contains/does not contain overlap
 */
bool CComboBox::isOverlap(CRect<int> &rect) {
  if (popUp) {
    int py(y + height + 1);
    rect = CRect<int> (x, py, x + width, py + comboItemHeight
        * comboItems.size());
    return true;
  }
  return false;
}
//---------------------------------------------------------------------------

/**
 * setComboItems - replaces list of items with new one
 * @param comboItems
 */
void CComboBox::setComboItems(vector<CTextListItem> comboItems) {
  this->comboItems = comboItems;
  sel = this->comboItems.begin();
  this->text = (*this->sel).getValue();
}
//---------------------------------------------------------------------------

/**
 * setComboItems - replaces list of items with new one
 * @param comboItems
 */
void CComboBox::setComboItems(vector<string> comboItems) {
  this->comboItems.clear();
  vector<string>::iterator i = comboItems.begin();
  for (int pos = 0; i < comboItems.end(); i++, pos++) {
    this->comboItems.push_back(CTextListItem(*i, pos));
  }
  sel = this->comboItems.begin();
  this->text = (*this->sel).getValue();
}
//---------------------------------------------------------------------------

/**
 * setComboItems - replaces list of items with new one
 * @param comboItems
 * @param comboItemIds
 */
void CComboBox::setComboItems(vector<string> comboItems,
    vector<int> comboItemIds) {

  // Checking sizes
  if (comboItems.size() != comboItemIds.size()) {
    throw CInvalidSizeException(getClassName(), "setComboItems");
  }

  // Setting items
  this->comboItems.clear();
  vector<string>::iterator i = comboItems.begin();
  vector<int>::iterator j = comboItemIds.begin();
  for (; i < comboItems.end(); i++, j++) {
    this->comboItems.push_back(CTextListItem(*i, *j));
  }
  sel = this->comboItems.begin();
  this->text = (*this->sel).getValue();
}
//---------------------------------------------------------------------------
